package com.campus.controller.Schedule;

import com.campus.mapper.*;
import com.campus.service.UploadService;
import com.qiniu.common.QiniuException;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class FileSchedule {

    @Resource
    private FileMapper fileMapper;
    @Resource
    private FileUploadMapper fileUploadMapper;
    @Resource
    private RoomManagerMapper roomManagerMapper;
    @Resource
    private InfoMapper infoMapper;
    @Resource
    private TeacherMapper teacherMapper;
    @Autowired
    private UploadService uploadService;
    @Resource
    private StudentMapper studentMapper;

    @Value("${qiniu.accessKey}")
    private String accessKey;
    @Value("${qiniu.secretKey}")
    private String secretKey;
    @Value("${qiniu.bucket}")
    private String bucket;
    @Value("${qiniu.prefix}")
    private String prefix;

    @Scheduled(cron = "0 0 2 * * ?")
    public void clearingFile() {
        log.error("定时清理正在执行");
        //        使用公钥和秘钥进行七牛云验证
        Configuration cfg = new Configuration(Region.huadong());
        Auth auth = Auth.create(accessKey, secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        int limit = 1000;
        String delimiter = "";
        //        指定操作bucket空间
        BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(bucket, "", limit, delimiter);
        //        toDeleteFile集合代表七牛云中所有文件
        Set<String> toDeleteFile = new HashSet<>();
        //        filesInDb表示所有数据库中的文件名，这里先查找t_file表中的数据，并除去前缀
        Set<String> filesInDb = fileMapper.selectList(null)
                .stream()
                .map(file -> file.getPath()
                        .substring(prefix.length() + 1))
                .collect(Collectors.toSet());
        //        将t_file_upload表的文件名添加到filesInDb集合中，也除去前缀
        filesInDb.addAll(
                fileUploadMapper.selectList(null)
                        .stream()
                        .map(fileUpload -> fileUpload.getPath()
                                .substring(prefix.length() + 1))
                        .collect(Collectors.toSet()));
        filesInDb.addAll(teacherMapper.selectList(null)
                .stream()
                .map(avatar -> avatar.getAvatar()
                        .substring(prefix.length() + 1))
                .collect(Collectors.toSet()));
        filesInDb.addAll(infoMapper.selectList(null)
                .stream()
                .map(imgSrc -> imgSrc.getImgSrc()
                        .substring(prefix.length() + 1))
                .collect(Collectors.toSet()));
        filesInDb.addAll(studentMapper.selectList(null)
                .stream()
                .map(avatar -> avatar.getAvatar()
                        .substring(prefix.length() + 1))
                .collect(Collectors.toSet()));
        filesInDb.addAll(roomManagerMapper.selectList(null)
                .stream()
                .map(avatar -> avatar.getAvatar()
                        .substring(prefix.length() + 1))
                .collect(Collectors.toSet()));
        //        将七牛云中所有文件加入到删除集合中
        while (fileListIterator.hasNext()) {
            FileInfo[] items = fileListIterator.next();
            for (FileInfo item : items) {
                toDeleteFile.add(item.key);
            }
        }

        //        使用集合中的减法运算得到存在于七牛云中，而不存在于数据库中的文件名
        toDeleteFile.removeAll(filesInDb);
        List<String> fileList = new ArrayList<>(toDeleteFile);
        //        由于七牛云限制一次最多操作1000条，所以使用循环多次进行删除文件，trycatch代码块中为七牛云官方实例
        for (int i = 0; i < fileList.size(); i += 1000) {
            int endIndex = Math.min(i + 1000, fileList.size());
            String[] keyList = fileList.subList(i, endIndex).toArray(new String[endIndex - i]);
            uploadService.deleteFileFromQiniu(keyList);
        }
    }

}
